// Command Line Arguments (命令行参数) 示例
// 演示 Pascal 中命令行参数处理的各种用法
program p_42_command_line_arguments;

{$mode objfpc}{$H+}
// {$mode objfpc} 启用 Object Pascal 模式
// {$H+} 启用长字符串支持（AnsiString）

// 引入单元文件
uses
  SysUtils,      // 系统工具单元
  Classes;       // 类单元

// 显示所有命令行参数
procedure DisplayAllParameters;
var
  i: Integer;
begin
  WriteLn('所有命令行参数:');
  WriteLn('  参数总数: ', ParamCount);
  
  for i := 0 to ParamCount do
  begin
    if i = 0 then
      WriteLn('  参数[', i, '] (程序名): ', ParamStr(i))
    else
      WriteLn('  参数[', i, ']: ', ParamStr(i));
  end;
end;

// 解析位置参数
procedure ParsePositionalArguments;
var
  param1, param2, param3: String;
begin
  WriteLn('位置参数解析:');
  
  if ParamCount >= 1 then
  begin
    param1 := ParamStr(1);
    WriteLn('  第一个参数: ', param1);
  end
  else
    WriteLn('  未提供第一个参数');
  
  if ParamCount >= 2 then
  begin
    param2 := ParamStr(2);
    WriteLn('  第二个参数: ', param2);
  end
  else
    WriteLn('  未提供第二个参数');
  
  if ParamCount >= 3 then
  begin
    param3 := ParamStr(3);
    WriteLn('  第三个参数: ', param3);
  end
  else
    WriteLn('  未提供第三个参数');
end;

// 解析命名参数
procedure ParseNamedArguments;
var
  i: Integer;
  arg: String;
  paramName, paramValue: String;
  equalPos: Integer;
begin
  WriteLn('命名参数解析:');
  
  for i := 1 to ParamCount do
  begin
    arg := ParamStr(i);
    
    // 检查是否为命名参数（格式：--name=value 或 -name=value）
    if (Copy(arg, 1, 2) = '--') or (Copy(arg, 1, 1) = '-') then
    begin
      equalPos := Pos('=', arg);
      if equalPos > 0 then
      begin
        // 格式：--name=value
        paramName := Copy(arg, 1, equalPos - 1);
        paramValue := Copy(arg, equalPos + 1, Length(arg));
        WriteLn('  参数 ', paramName, ' = ', paramValue);
      end
      else
      begin
        // 格式：--flag 或 -flag
        WriteLn('  标志参数: ', arg);
      end;
    end
    else
    begin
      // 位置参数
      WriteLn('  位置参数[', i, ']: ', arg);
    end;
  end;
end;

// 参数类型转换示例
procedure ParameterTypeConversion;
var
  i: Integer;
  arg: String;
  intValue: Integer;
  floatValue: Double;
  boolValue: Boolean;
begin
  WriteLn('参数类型转换:');
  
  for i := 1 to ParamCount do
  begin
    arg := ParamStr(i);
    Write('  参数[', i, '] = ', arg);
    
    // 尝试转换为整数
    if TryStrToInt(arg, intValue) then
    begin
      WriteLn(' (整数: ', intValue, ')');
      Continue;
    end;
    
    // 尝试转换为浮点数
    if TryStrToFloat(arg, floatValue) then
    begin
      WriteLn(' (浮点数: ', floatValue:0:2, ')');
      Continue;
    end;
    
    // 尝试转换为布尔值
    if TryStrToBool(arg, boolValue) then
    begin
      WriteLn(' (布尔值: ', BoolToStr(boolValue, True), ')');
      Continue;
    end;
    
    WriteLn(' (字符串)');
  end;
end;

// 显示帮助信息
procedure ShowHelp;
begin
  WriteLn('帮助信息:');
  WriteLn('  用法: ', ParamStr(0), ' [选项] [参数]');
  WriteLn('  选项:');
  WriteLn('    --help, -h        显示帮助信息');
  WriteLn('    --version, -v     显示版本信息');
  WriteLn('    --name=value      设置名称');
  WriteLn('    --count=value     设置计数');
  WriteLn('    --verbose         启用详细输出');
  WriteLn('');
  WriteLn('  示例:');
  WriteLn('    ', ParamStr(0), ' --name=张三 --count=5');
  WriteLn('    ', ParamStr(0), ' -v --verbose hello world');
end;

// 显示版本信息
procedure ShowVersion;
begin
  WriteLn('版本信息:');
  WriteLn('  命令行参数示例程序 v1.0');
  WriteLn('  使用 Free Pascal 编写');
end;

// 检查特殊参数
procedure CheckSpecialParameters;
var
  i: Integer;
  arg: String;
  showHelp: Boolean = False;
  showVersion: Boolean = False;
begin
  WriteLn('特殊参数检查:');
  
  for i := 1 to ParamCount do
  begin
    arg := LowerCase(ParamStr(i));
    
    if (arg = '--help') or (arg = '-h') then
    begin
      showHelp := True;
      Break;
    end;
    
    if (arg = '--version') or (arg = '-v') then
    begin
      showVersion := True;
      Break;
    end;
  end;
  
  if showHelp then
  begin
    ShowHelp;
    Halt(0);  // 正常退出
  end;
  
  if showVersion then
  begin
    ShowVersion;
    Halt(0);  // 正常退出
  end;
  
  if not showHelp and not showVersion then
    WriteLn('  没有检测到特殊参数');
end;

// 参数验证示例
procedure ValidateParameters;
var
  requiredCount: Integer = 2;
begin
  WriteLn('参数验证:');
  
  if ParamCount = 0 then
  begin
    WriteLn('  错误: 未提供任何参数');
    WriteLn('  使用 --help 查看帮助信息');
    Exit;
  end;
  
  if ParamCount < requiredCount then
  begin
    WriteLn('  错误: 至少需要 ', requiredCount, ' 个参数，当前提供 ', ParamCount, ' 个');
    Exit;
  end;
  
  if ParamCount > 5 then
  begin
    WriteLn('  警告: 提供了过多参数 (', ParamCount, ' 个)，仅使用前5个');
  end;
  
  WriteLn('  参数验证通过');
end;

// 程序主入口
begin
  WriteLn('=== Pascal 命令行参数示例 ===');
  WriteLn;
  
  // 1. 显示所有命令行参数
  DisplayAllParameters;
  
  WriteLn;
  
  // 2. 解析位置参数
  ParsePositionalArguments;
  
  WriteLn;
  
  // 3. 解析命名参数
  ParseNamedArguments;
  
  WriteLn;
  
  // 4. 参数类型转换
  ParameterTypeConversion;
  
  WriteLn;
  
  // 5. 检查特殊参数
  CheckSpecialParameters;
  
  WriteLn;
  
  // 6. 参数验证
  ValidateParameters;
  
  WriteLn;
  WriteLn('演示了 Pascal 中命令行参数处理的各种用法');
  WriteLn;
  WriteLn('提示: 尝试使用以下命令行运行程序:');
  WriteLn('  ', ParamStr(0), ' --help');
  WriteLn('  ', ParamStr(0), ' --version');
  WriteLn('  ', ParamStr(0), ' --name=张三 --count=5 --verbose');
  WriteLn('  ', ParamStr(0), ' hello world 42 3.14 true');
  
  // 等待用户按键，防止程序窗口立即关闭
  ReadLn;
end.